package com.ruoyi.commodity.service.impl;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ruoyi.commodity.domain.*;
import com.ruoyi.commodity.domain.vo.ProductVO;
import com.ruoyi.commodity.mapper.*;
import com.ruoyi.commodity.service.ProductImageBase;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.*;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.depot.domain.ProductRemarkImage;
import com.ruoyi.depot.mapper.ProductRemarkImageMapper;
import com.ruoyi.system.mapper.SysDictDataMapper;
import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.ruoyi.commodity.service.IProductService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.NumberUtils;
import org.springframework.web.multipart.MultipartFile;

import static com.ruoyi.common.core.page.TableSupport.PAGE_NUM;
import static com.ruoyi.common.core.page.TableSupport.PAGE_SIZE;

/**
 * 产品管理Service业务层处理
 *
 * @author ruoyi
 * @date 2023-09-09
 */
@Service
public class ProductServiceImpl implements IProductService {
	private static final Logger logger = LogManager.getLogger(QualityTemplateServiceImpl.class);
	@Autowired
	private ProductMapper productMapper;

	@Autowired
	private ProductSkuMapper productSkuMapper;

	@Autowired
	private OemMapper oemMapper;

	@Autowired
	private ProductCustomQualityItemMapper productCustomQualityItemMapper;

	@Autowired
	private ProductImagesMapper productImagesMapper;

	@Autowired
	private ProductImageMapper productImageMapper;

	@Autowired
	private ProductRemarkImageMapper productRemarkImageMapper;

	@Autowired
	private QualityTemplateImagesMapper qualityTemplateImagesMapper;

	@Autowired
	private AuthBrandMapper authBrandMapper;

	@Autowired
	private ComboSkuRecordsMapper comboSkuRecordsMapper;

	@Autowired
	private productCatesMapper productCatesMapper;

	@Autowired
	private ColorMapper colorMapper;

	@Autowired
	private SysDictDataMapper sysDictDataMapper;

	@Value("${ruoyi.profile}")
	private String basePath;

	// 需要返回的 URL 前缀
	private static final String URL_PREFIX = "/profile/upload/";

	/**
	 * 查询产品管理
	 *
	 * @param id 产品管理主键
	 * @return 产品管理
	 */
	@Override
	public ProductVO selectProductById(Long id) {
		// 查询产品信息
		Product product = productMapper.selectProductById(id);
		if (product == null) {
			throw new ServiceException("当前产品信息不存在！");
		}

		// 查询产品SKU
		ProductSku productSku = productSkuMapper.selectProductSkuById(id);
		if (productSku != null) {
			BeanUtils.copyProperties(productSku, product);
		}

		ProductVO productVO = new ProductVO();
		BeanUtils.copyProperties(product, productVO);
		List<String> collect = Arrays.stream(productVO.getAttribute().split(","))
				.collect(Collectors.toList());
		productVO.setAttributes(collect);
		// 查询对应的产品质检项
		List<ProductCustomQualityItem> qualityItems = productCustomQualityItemMapper.selectList(
				new LambdaQueryWrapper<ProductCustomQualityItem>()
						.eq(ProductCustomQualityItem::getProductId, id.intValue())
		);


		if (qualityItems != null) {
			productVO.setCustomQualityCheck(qualityItems);
		}
		// 查询对应产品的质检图片信息
		List<String> productImages = productImagesMapper.selectList(
						new LambdaQueryWrapper<ProductImages>()
								.eq(ProductImages::getProductId, id.intValue())
				).stream()
				.map(productImage -> productImage.getImagePath().trim())
				.collect(Collectors.toList());

		if (!productImages.isEmpty()) {
			productVO.setImages(productImages);
		}

		//查询产品图片信息
		List<String> image = productImageMapper.selectList(
						new LambdaQueryWrapper<ProductImage>()
								.eq(ProductImage::getProductId, id.intValue())
				).stream()
				.map(productImage -> productImage.getProductImagePath().trim())
				.collect(Collectors.toList());

		if (!image.isEmpty()) {
			productVO.setImgName(image);
		}

		//查询产品备注图片信息
		List<String> remarkImage = productRemarkImageMapper.selectList(
						new LambdaQueryWrapper<ProductRemarkImage>()
								.eq(ProductRemarkImage::getProductId, id.intValue())
				).stream()
				.map(productImage -> productImage.getProductRemarkImagePath().trim())
				.collect(Collectors.toList());

		if (!image.isEmpty()) {
			productVO.setProductRemarksImgName(remarkImage);
		}
		return productVO;
	}


	/**
	 * 查询产品管理列表
	 *
	 * @param product 产品管理
	 * @return 产品管理
	 */
	@Override
//	@DataScope(skuAlias = "ps", productAlias = "p")
	public PageInfo<ProductVO> selectProductList(ProductVO product) {
		// 调用分页查询：注意这里只调用一次 PageHelper.startPage
		PageHelper.startPage(product.getPageNum(), product.getPageSize());
		List<ProductVO> productList = productMapper.selectProductList(product);

		// 收集产品ID
		Set<Long> productIds = productList.stream()
				.map(ProductVO::getId)
				.collect(Collectors.toSet());

		// 如果没有产品ID，直接返回空的 PageInfo 对象
		if (productIds.isEmpty()) {
			PageInfo<ProductVO> emptyPage = new PageInfo<>(productList);
			emptyPage.setList(Collections.emptyList());
			return emptyPage;
		}

		// 批量查询质检项
		Map<Integer, List<ProductCustomQualityItem>> qualityItemsMap = productCustomQualityItemMapper.selectList(
						new LambdaQueryWrapper<ProductCustomQualityItem>()
								.in(ProductCustomQualityItem::getProductId, productIds))
				.stream()
				.collect(Collectors.groupingBy(ProductCustomQualityItem::getProductId));

		// 批量查询商品图片（质检信息图片）
		Map<Integer, List<String>> imagesMap = productImagesMapper.selectList(
						new LambdaQueryWrapper<ProductImages>()
								.in(ProductImages::getProductId, productIds))
				.stream()
				.collect(Collectors.groupingBy(ProductImages::getProductId,
						Collectors.mapping(s -> s.getImagePath().trim(), Collectors.toList())));

		// 批量查询商品图片
		Map<Integer, List<String>> imageMap = productImageMapper.selectList(
						new LambdaQueryWrapper<ProductImage>()
								.in(ProductImage::getProductId, productIds))
				.stream()
				.collect(Collectors.groupingBy(ProductImage::getProductId,
						Collectors.mapping(s -> s.getProductImagePath().trim(), Collectors.toList())));

		// 对查询结果进行转换
		List<ProductVO> convertedList = productList.stream().map(p -> {
			ProductVO productVO = new ProductVO();
			BeanUtils.copyProperties(p, productVO);

			List<ProductCustomQualityItem> qualityItems = qualityItemsMap.getOrDefault(p.getId().intValue(), Collections.emptyList());
			List<String> images = imagesMap.getOrDefault(p.getId().intValue(), Collections.emptyList());
			List<String> productImages = imageMap.getOrDefault(p.getId().intValue(), Collections.emptyList());

			productVO.setCustomQualityCheck(qualityItems);
			productVO.setImages(images);
			productVO.setImgName(productImages);
			return productVO;
		}).collect(Collectors.toList());

		// 用 PageInfo 包装原始列表，此时 PageInfo 内部已包含正确的 total 值
		PageInfo<ProductVO> pageInfo = new PageInfo<>(productList);
		// 更新转换后的列表
		pageInfo.setList(convertedList);
		return pageInfo;
	}



	@Override
	public List<Product> selectProductListById(Long[] ids) {
		return productMapper.selectProductListById(ids);
	}

	/**
	 * 新增产品管理
	 *
	 * @param product 产品管理
	 * @return 结果
	 */
	@Transactional
	@Override
	public int insertProduct(ProductVO product) {
		if (product == null) {
			throw new ServiceException("传入的产品信息不能为空");
		}

		Product p = new Product();
		BeanUtils.copyProperties(product, p);
		if (product.getFlag() != null && product.getFlag() == 1) {
			// 查询组合产品sku是否已经存在
			Long count  = comboSkuRecordsMapper.selectCount(new LambdaUpdateWrapper<ComboSkuRecords>()
					.eq(ComboSkuRecords::getComboSku, product.getSku()));

			if(count > 0){
				throw new ServiceException("组合sku:"+product.getSku()+"已经存在！");
			}
			p.setSku(product.getSku());
			// 解析组合sku数据
			List<ComboSkuRecords> comboSkuRecords = parseComboSKU(product.getSku());
			// 批量插入关联数据
			int result = comboSkuRecordsMapper.insertBatch(comboSkuRecords);
			if(result <= 0){
				throw new ServiceException("插入组合产品数据失败，请重试!");
			}
		} else if(product.getVariantOperation() != null && product.getVariantOperation()) {
			// 变体操作插入对应的新sku数据
			String sku = generateVariantSKU(product.getSku());
			p.setSku(sku);
		} else {
			p.setSku(skuName(product.getOem()));
		}

		// 拼接属性
		String attribute = product.getAttributes().stream()
				.map(Object::toString)
				.collect(Collectors.joining(","));

		p.setAttribute(attribute);
		p.setProNo(generateCodePlan());
		p.setAddTime(DateUtils.getNowDate());
		p.setTemplateId(product.getTemplateId()); // 选择的质检模板
		p.setInspectionMethod(product.getInspectionMethod()); // 质检方式
		// 查询数据库，判断 SKU 是否已存在
		int skuCount = productMapper.countByProductSku(p.getSku());
		if (skuCount > 0) {
			throw new RuntimeException("SKU 已存在：" + p.getSku());
		}
		int insertCount = productMapper.insertProduct(p);
		if (insertCount == 0) {
			throw new ServiceException("插入产品失败");
		}

		Long productId = p.getId();

		// 插入产品SKU
		ProductSku productSku = new ProductSku();
		BeanUtils.copyProperties(product, productSku);
		productSku.setProductId(productId);
		productSkuMapper.insertProductSku(productSku);

		// 添加自定义质检项
		List<ProductCustomQualityItem> qualityItems = new ArrayList<>();
		if (product.getCustomQualityCheck() != null) {
			product.getCustomQualityCheck().forEach(s -> {
				ProductCustomQualityItem item = new ProductCustomQualityItem();
				item.setProductId(productId.intValue());
				item.setInspectionItem(s.getInspectionItem());
				item.setInspectionContent(s.getInspectionContent());
				qualityItems.add(item);
			});
			if (!qualityItems.isEmpty()) {
				productCustomQualityItemMapper.insertBatch(qualityItems);
			}
		}

		// 添加对应的质检图片
		if (product.getImages() != null) {
			List<ProductImages> images = product.getImages().stream()
					.map(String::trim)  // 清理字符串
					.filter(imagePath -> !imagePath.isEmpty())  // 过滤空字符串
					.map(imagePath -> {
						ProductImages image = new ProductImages();
						image.setProductId(productId.intValue());
						image.setImagePath(imagePath);
						image.setCreatedAt(new Date());
						return image;
					})
					.collect(Collectors.toList());

			if (!images.isEmpty()) {
				productImagesMapper.insertBatch(images);
			}
		}

		// 添加对应的商品图片
		if (product.getImgName() != null) {
			List<ProductImage> productImages = product.getImgName().stream()
					.map(String::trim)  // 清理字符串
					.filter(imagePath -> !imagePath.isEmpty())  // 过滤空字符串
					.map(imagePath -> {
						ProductImage image = new ProductImage();
						image.setProductId(productId.intValue());
						image.setProductImagePath(imagePath);
						image.setCreatedAt(new Date());
						return image;
					})
					.collect(Collectors.toList());

			if (!productImages.isEmpty()) {
				productImageMapper.insertBatch(productImages);
			}
		}

		// 添加对应的商品备注图片
		if (product.getProductRemarksImgName() != null) {
			List<ProductRemarkImage> productRemarkImages = product.getProductRemarksImgName().stream()
					.map(String::trim)  // 清理字符串
					.filter(imagePath -> !imagePath.isEmpty())  // 过滤空字符串
					.map(imagePath -> {
						ProductRemarkImage image = new ProductRemarkImage();
						image.setProductId(productId.intValue());
						image.setProductRemarkImagePath(imagePath);
						image.setCreatedAt(new Date());
						return image;
					})
					.collect(Collectors.toList());

			if (!productRemarkImages.isEmpty()) {
				productRemarkImageMapper.insertBatch(productRemarkImages);
			}
		}

		return insertCount;
	}


	@Transactional
	public String generateVariantSKU(String baseSKU) {
		// 查询已有的最大后缀值
		Integer maxSuffix = productMapper.getMaxSuffix(baseSKU);
		// 如果没有记录，则从 1 开始；否则在最大值基础上加 1
		int newSuffix = (maxSuffix == null) ? 1 : maxSuffix + 1;
		// 格式化为两位数字，例如 1 格式化为 "01"
		String formattedSuffix = String.format("%02d", newSuffix);
		// 拼接生成新的 SKU
		return baseSKU + "-" + formattedSuffix;
	}

	// 解析组合 SKU 字符串的方法
	public List<ComboSkuRecords> parseComboSKU(String comboSKU) {
		List<ComboSkuRecords> recordList = new ArrayList<>();
		// 使用正则表达式分割，注意要转义+号
		String[] parts = comboSKU.split("\\+");
		for (String part : parts) {
			part = part.trim();
			if (part.contains("*")) {
				// 包含*则拆分出 sku 和数量
				String[] arr = part.split("\\*");
				String sku = arr[0].trim();
				int qty = Integer.parseInt(arr[1].trim());
				recordList.add(new ComboSkuRecords(comboSKU, sku, qty));
			} else {
				// 不包含*，数量默认为1
				recordList.add(new ComboSkuRecords(comboSKU, part, 1));
			}
		}
		return recordList;
	}

	/**
	 * 生成随机数
	 *
	 * @return
	 */
	public String generateCodePlan() {
		String proNo = productMapper.selectProNo();
		String randomNumber;
		// ...根据自己的业务逻辑实现获取序列号的方法
		if (StringUtils.isEmpty(proNo)) {
			randomNumber = Constants.RANDOM_NUMBERS;
		} else {
			// 将 proNo 解析为整数，加一，然后转换回字符串
			int incrementedProNo = Integer.parseInt(proNo) + 1;
			randomNumber = Integer.toString(incrementedProNo);
		}
		return randomNumber;
	}

	/**
	 * 修改产品管理
	 *
	 * @param productVO 产品管理
	 * @return 结果
	 */
	@Transactional
	@Override
	public int updateProduct(ProductVO productVO) {
		if (productVO == null) {
			throw new ServiceException("传入的产品信息不能为空");
		}
		int updateCount = 0;
		if(productVO.getVariantOperation() != null && productVO.getVariantOperation()){
			if(productVO.getSku().contains("-")){
				throw new ServiceException("原始SKU["+productVO.getSku()+"]已是变体产品，禁止二次变体");
			}
			// 变体产品执行新增操作
			updateCount = insertProduct(productVO);
		} else {
			// 正常修改产品
			updateCount = editProduct(productVO);
		}
		return updateCount;
	}

	private int editProduct(ProductVO productVO) {
		Product p = new Product();
		// 拼接属性
		String attribute = productVO.getAttributes().stream()
				.map(Object::toString)
				.collect(Collectors.joining(","));
		productVO.setAttribute(attribute);
		BeanUtils.copyProperties(productVO, p);
		p.setTemplateId(productVO.getTemplateId()); // 选择的质检模板
		p.setInspectionMethod(productVO.getInspectionMethod()); // 质检方式
		int updateCount = productMapper.updateProduct(p);
		if (updateCount == 0) {
			throw new ServiceException("更新产品失败");
		}

		Long productId = p.getProductId();

		// 更新产品SKU
		ProductSku productSku = new ProductSku();
		BeanUtils.copyProperties(productVO, productSku);
		productSku.setProductId(productId);
		productSkuMapper.updateProductSku(productSku);


		// 删除产品相关的质检项
		productCustomQualityItemMapper.delete(new LambdaQueryWrapper<ProductCustomQualityItem>().eq(ProductCustomQualityItem::getProductId, productId.intValue()));
		List<ProductCustomQualityItem> qualityItems = new ArrayList<>();
		if (productVO.getCustomQualityCheck() != null) {
			productVO.getCustomQualityCheck().forEach(s -> {
				ProductCustomQualityItem item = new ProductCustomQualityItem();
				item.setProductId(productId.intValue());
				item.setInspectionItem(s.getInspectionItem());
				item.setInspectionContent(s.getInspectionContent());
				qualityItems.add(item);
			});
			if (!qualityItems.isEmpty()) {
				productCustomQualityItemMapper.insertBatch(qualityItems);
			}
		}

		// 处理产品图片
		List<String> originalImagePaths = productImagesMapper.selectList(
						new LambdaQueryWrapper<ProductImages>().eq(ProductImages::getProductId, productId.intValue())
				).stream()
				.map(ProductImages::getImagePath)
				.collect(Collectors.toList());

		// 过滤掉不再使用的图片
		List<String> imagesToDelete = new ArrayList<>(originalImagePaths);
		if (productVO.getImages() != null) {
			List<String> updatedImagePaths = productVO.getImages().stream()
					.map(String::trim)  // 清理字符串
					.filter(imagePath -> !imagePath.isEmpty())  // 过滤空字符串
					.collect(Collectors.toList());

			// 删除数据库中不再使用的图片记录
			imagesToDelete.removeAll(updatedImagePaths);

			// 删除操作前检查图片路径
			if (!imagesToDelete.isEmpty()) {
				productImagesMapper.delete(new LambdaQueryWrapper<ProductImages>().in(ProductImages::getImagePath, imagesToDelete));
				// 删除物理文件
				deleteFile(imagesToDelete);  // 这里调用你提供的删除方法
			}

			// 删除原有图片后，插入新的图片前，先删除当前产品的所有图片
			productImagesMapper.delete(new LambdaQueryWrapper<ProductImages>().eq(ProductImages::getProductId, productId.intValue()));

			// 更新数据库中的图片
			List<ProductImages> images = updatedImagePaths.stream()
					.map(imagePath -> {
						ProductImages image = new ProductImages();
						image.setProductId(productId.intValue());
						image.setImagePath(imagePath);
						image.setCreatedAt(new Date());
						return image;
					})
					.collect(Collectors.toList());

			if (!images.isEmpty()) {
				productImagesMapper.insertBatch(images);
			}
		}

		// 处理商品图片
		List<String> originalProductImagePaths = productImageMapper.selectList(
						new LambdaQueryWrapper<ProductImage>().eq(ProductImage::getProductId, productId.intValue())
				).stream()
				.map(ProductImage::getProductImagePath)
				.collect(Collectors.toList());

		List<String> productImagesToDelete = new ArrayList<>(originalProductImagePaths);
		if (productVO.getImgName() != null) {
			List<String> updatedProductImagePaths = productVO.getImgName().stream()
					.map(String::trim)  // 清理字符串
					.filter(imagePath -> !imagePath.isEmpty())  // 过滤空字符串
					.collect(Collectors.toList());

			// 删除数据库中不再使用的商品图片记录
			productImagesToDelete.removeAll(updatedProductImagePaths);

			// 删除操作前检查图片路径
			if (!productImagesToDelete.isEmpty()) {
				productImageMapper.delete(new LambdaQueryWrapper<ProductImage>().in(ProductImage::getProductImagePath, productImagesToDelete));
				// 删除物理文件
				deleteFile(productImagesToDelete);  // 这里调用你提供的删除方法
			}

			// 删除原有商品图片后，插入新的商品图片前，先删除当前产品的所有商品图片
			productImageMapper.delete(new LambdaQueryWrapper<ProductImage>().eq(ProductImage::getProductId, productId.intValue()));

			// 更新商品图片
			List<ProductImage> productImages = updatedProductImagePaths.stream()
					.map(imagePath -> {
						ProductImage image = new ProductImage();
						image.setProductId(productId.intValue());
						image.setProductImagePath(imagePath);
						image.setCreatedAt(new Date());
						return image;
					})
					.collect(Collectors.toList());

			if (!productImages.isEmpty()) {
				productImageMapper.insertBatch(productImages);
			}
		}


		// 处理商品备注图片
		List<String> productRemarkImagesToDelete = productRemarkImageMapper.selectList(
						new LambdaQueryWrapper<ProductRemarkImage>().eq(ProductRemarkImage::getProductId, productId.intValue())
				).stream()
				.map(ProductRemarkImage::getProductRemarkImagePath).collect(Collectors.toList());
		if (productVO.getProductRemarksImgName() != null) {
			List<String> updatedProductImagePaths = productVO.getProductRemarksImgName().stream()
					.map(String::trim)  // 清理字符串
					.filter(imagePath -> !imagePath.isEmpty())  // 过滤空字符串
					.collect(Collectors.toList());

			// 删除数据库中不再使用的商品图片记录
			productRemarkImagesToDelete.removeAll(updatedProductImagePaths);

			// 删除操作前检查图片路径
			if (!productRemarkImagesToDelete.isEmpty()) {
				productRemarkImageMapper.delete(new LambdaQueryWrapper<ProductRemarkImage>().in(ProductRemarkImage::getProductRemarkImagePath, productRemarkImagesToDelete));
				// 删除物理文件
				deleteFile(productRemarkImagesToDelete);  // 这里调用你提供的删除方法
			}

			// 删除原有商品图片后，插入新的商品图片前，先删除当前产品的所有商品图片
			productRemarkImageMapper.delete(new LambdaQueryWrapper<ProductRemarkImage>().eq(ProductRemarkImage::getProductId, productId.intValue()));

			// 更新商品图片
			List<ProductRemarkImage> productImages = updatedProductImagePaths.stream()
					.map(imagePath -> {
						ProductRemarkImage image = new ProductRemarkImage();
						image.setProductId(productId.intValue());
						image.setProductRemarkImagePath(imagePath);
						image.setCreatedAt(new Date());
						return image;
					})
					.collect(Collectors.toList());

			if (!productImages.isEmpty()) {
				productRemarkImageMapper.insertBatch(productImages);
			}
		}
		return updateCount;
	}


	// 删除图片文件，直接删除
	private void deleteFile(List<String> imagePaths) {
		if (imagePaths == null || imagePaths.isEmpty()) {
			return;
		}
		for (String imagePath : imagePaths) {
			// 移除 imagePath 中的 '/profile' 前缀
			String prefixToRemove = "/profile";
			String adjustedImagePath = imagePath;
			if (imagePath.startsWith(prefixToRemove)) {
				adjustedImagePath = imagePath.substring(prefixToRemove.length());
			}
			// 检查该图片是否仍被其他模板引用
			int count = qualityTemplateImagesMapper.selectCount(
					new LambdaQueryWrapper<QualityTemplateImages>()
							.eq(QualityTemplateImages::getTemplateImagePath, imagePath)
			).intValue();
			if (count == 0) {
				// 删除图片文件
				File file = new File(basePath + adjustedImagePath);
				if (file.exists() && file.isFile()) {
					boolean deleted = file.delete();
					if (!deleted) {
						logger.warn("删除图片文件失败：" + file.getAbsolutePath());
					} else {
						logger.info("成功删除图片文件：" + file.getAbsolutePath());
					}
				} else {
					logger.info("图片文件不存在或不是文件，无需删除：" + file.getAbsolutePath());
				}
			}
		}
	}

	/**
	 * 批量删除产品管理
	 *
	 * @param ids 需要删除的产品管理主键
	 * @return 结果
	 */
	@Transactional
	@Override
	public int deleteProductByIds(Long[] ids) {
		if (ids == null || ids.length == 0) {
			throw new IllegalArgumentException("传入的删除id号为空，请刷新页面重试！");
		}

		try {
			// 批量删除相关的SKU、质检项
			int skuDeleted = productSkuMapper.deleteProductSkuByIds(ids);
			int qualityItemsDeleted = productCustomQualityItemMapper.delete(new LambdaQueryWrapper<ProductCustomQualityItem>()
					.in(ProductCustomQualityItem::getProductId, ids));

			// 批量删除产品相关的图片
			List<ProductImages> productImages = productImagesMapper.selectList(new LambdaQueryWrapper<ProductImages>()
					.in(ProductImages::getProductId, ids));
			int imagesDeleted = productImagesMapper.delete(new LambdaQueryWrapper<ProductImages>()
					.in(ProductImages::getProductId, ids));

			// 批量删除商品图片
			List<ProductImage> productImageList = productImageMapper.selectList(new LambdaQueryWrapper<ProductImage>()
					.in(ProductImage::getProductId, ids));
			int productImagesDeleted = productImageMapper.delete(new LambdaQueryWrapper<ProductImage>()
					.in(ProductImage::getProductId, ids));

			// 删除相关图片文件
			deleteFiles(productImages);
			deleteFiles(productImageList);

			// 删除产品本身
			int productDeleted = productMapper.deleteProductByIds(ids);

			// 记录每一步的删除结果
			logger.info("删除产品ID: {} 的相关数据，共删除SKU: {}, 质检项: {}, 产品图片: {}, 商品图片: {}, 产品本身: {}",
					Arrays.toString(ids), skuDeleted, qualityItemsDeleted, imagesDeleted, productImagesDeleted, productDeleted);

			// 返回所有删除操作的合计结果
			return skuDeleted + qualityItemsDeleted + imagesDeleted + productImagesDeleted + productDeleted;

		} catch (Exception e) {
			// 记录详细异常信息
			logger.error("删除产品ID: {} 时发生异常: ", Arrays.toString(ids), e);
			throw new RuntimeException("删除产品数据失败！", e);
		}
	}

	// 删除图片文件，先检查图片是否仍被引用
	private void deleteFiles(List<? extends ProductImageBase> productImages) {
		if (productImages != null && !productImages.isEmpty()) {
			for (ProductImageBase productImage : productImages) {
				String imagePath = productImage.getImagesPath();

				// 移除 imagePath 中的 '/profile' 前缀（根据实际需求调整）
				String prefixToRemove = "/profile";
				String adjustedImagePath = imagePath;
				if (imagePath.startsWith(prefixToRemove)) {
					adjustedImagePath = imagePath.substring(prefixToRemove.length());
				}

				// 检查该图片是否仍被其他模板引用
				int count = qualityTemplateImagesMapper.selectCount(
						new LambdaQueryWrapper<QualityTemplateImages>()
								.eq(QualityTemplateImages::getTemplateImagePath, imagePath)
				).intValue();

				// 如果该图片不被引用，进行删除操作
				if (count == 0) {
					// 文件路径调整为完整路径
					File file = new File(basePath + adjustedImagePath);

					if (file.exists() && file.isFile()) {
						boolean deleted = file.delete();
						if (!deleted) {
							// 删除失败，记录警告日志
							logger.warn("删除图片文件失败：" + file.getAbsolutePath());
						} else {
							// 删除成功，记录信息日志
							logger.info("成功删除图片文件：" + file.getAbsolutePath());
						}
					} else {
						// 文件不存在，记录信息日志
						logger.info("图片文件不存在或不是文件，无需删除：" + file.getAbsolutePath());
					}
				} else {
//					// 图片仍被引用，不删除物理文件，记录信息日志
					logger.info("图片仍被引用，未删除文件：" + imagePath);
				}
			}
		}
	}


	/**
	 * 删除产品管理信息
	 *
	 * @param id 产品管理主键
	 * @return 结果
	 */
	@Override
	public int deleteProductById(Long id) {
		return productMapper.deleteProductById(id);
	}


	@Override
	public String productSku(String oemName) {
		return productMapper.productSku(oemName);
	}

	@Override
	public String skuName(Long oem) {
		Oem oemById = oemMapper.selectOemById(oem);
		String sku = productMapper.productSku(oemById.getName());
		if (StringUtils.isEmpty(sku)) {
			String number = Constants.AUXILIARY_NUMBER;
			return oemById.getName() + (number + 1);
		} else {
			return oemById.getName() + String.format("%05d", (NumberUtils.parseNumber(sku.substring(2), Long.class) + 1));
		}
	}

	@Override
	public PageInfo<Product> selectProductBrand(Product product) {
		// 查询出店铺下的所有品牌
		List<AuthBrand> authBrands = authBrandMapper.selectBrandList(product.getAuthId());

		// 提取出该店铺下所有的品牌id
		List<Long> authBrandIds = authBrands.stream().map(AuthBrand::getAuthBrandId).collect(Collectors.toList());

		product.setAuthBrandIds(authBrandIds);

		// 调用分页查询：注意这里只调用一次 PageHelper.startPage
		PageHelper.startPage(product.getPageNum(), product.getPageSize());
		List<Product> products = productMapper.selectProductBrand(product);

		// 在产品列表不为空的情况下查询图片
		if (!products.isEmpty()) {
			// 提取所有的产品id
			List<Long> productIds = products.stream().map(Product::getId).collect(Collectors.toList());

			// 查询产品图片
			List<ProductImage> productImages = productImageMapper.selectProductImagesByProductId(productIds);

			// 按照产品id进行分组
			Map<Integer, List<String>> productImagePathMap = productImages.stream().collect(Collectors.groupingBy(ProductImage::getProductId, Collectors.mapping(ProductImage::getProductImagePath, Collectors.toList())));

			if (!productImagePathMap.isEmpty()) {
				// 为每个产品分配图片
				products.forEach(item -> {
					List<String> images = productImagePathMap.get(item.getId().intValue());
					if (images != null && !images.isEmpty()) {
						item.setImgName(images);
					}
				});
			}
		}
		PageInfo<Product> pageInfo = new PageInfo<>(products);
		pageInfo.setList(products);
		return pageInfo;
	}

	@Override
	public List<Product> selectByPlanId(Product product, Boolean isEdit) {
		// 如果是编辑状态，且未设置 shipmentsProductIds，则使用 shipmentsIds
		if (Boolean.TRUE.equals(isEdit) && product.getShipmentsProductIds() == null) {
			product.setShipmentsProductIds(product.getShipmentsIds());
		}

		// 根据 isEdit 的值选择不同的查询方法
		List<Product> products = Boolean.TRUE.equals(isEdit)
				? productMapper.selectByPlanIdAndShipmentsProductIds(product)
				: productMapper.selectByPlanIdAndShipmentsProductIdsByAdd(product);


		// 获取产品ID集合，避免空值
		List<Long> productIdList = products.stream()
				.map(Product::getProductId) // 过滤掉 productId 为空的产品
				.filter(Objects::nonNull)
				.collect(Collectors.toList());

		// 如果 productIdList 为空，直接返回空列表
		if (productIdList.isEmpty()) {
			return products;
		}

		// 根据产品ID批量查询产品图片
		List<ProductImage> productImages = productImageMapper.selectProductImagesByProductId(productIdList);

		// 将图片按照 productId 进行分组
		Map<Integer, List<String>> imageMap = productImages.stream()
				.collect(Collectors.groupingBy(
						ProductImage::getProductId,
						Collectors.mapping(ProductImage::getProductImagePath, Collectors.toList())
				));

		// 遍历产品列表，为每个产品设置图片，注意需要进行非空判断
		products.forEach(item -> {
			if (item.getProductId() != null) { // 只有 productId 不为空时才进行处理
				List<String> imgs = imageMap.get(item.getProductId().intValue());
				if (imgs != null && !imgs.isEmpty()) {
					item.setImgName(imgs);
				}
			}
		});

//		List<Product> additionalSubProducts = new ArrayList<>();
//		List<Product> productsToRemove = new ArrayList<>();
//
//		// 处理组合sku的逻辑
//		products.forEach(item -> {
//			if (item.getSku() != null && item.getSku().contains("+")) {  // 判断是否为组合 SKU
//				// 按 "+" 拆分，得到每个 sku 部分
//				String[] skuParts = item.getSku().split("\\+");
//				// 注意：避免在遍历 products 时直接修改集合，建议将拆分后的产品存入另一个集合中
//				List<Product> subProducts = new ArrayList<>();
//				for (String skuPart : skuParts) {
//					int quantity = 1;
//					String sku = skuPart;
//					// 如果包含 "*" 则解析数量
//					if (skuPart.contains("*")) {
//						String[] skuDetails = skuPart.split("\\*");
//						sku = skuDetails[0];
//						try {
//							quantity = Integer.parseInt(skuDetails[1]);
//						} catch (NumberFormatException e) {
//							throw new ServiceException("解析组合sku数量出现异常，请联系管理员进行检查！");
//						}
//					}
//					// 查询单个 sku 的产品信息
//					Product subProduct = productMapper.selectBySku(sku);
//					if (subProduct != null) {
//						// 取组合 sku 对应的 openSize，假设它代表组合sku的基数
//						Long openSize = item.getOperSize() == null ? 0L : item.getOperSize();
//						// 计算单个 sku 的实际数量
//						Long totalQuantity = openSize * quantity;
//						subProduct.setOperSize(totalQuantity);  // 更新数量
//						// 计算金额：单价 * 数量
//						BigDecimal amount = BigDecimal.valueOf(totalQuantity).multiply(subProduct.getPrice());
//						subProduct.setAmount(amount);
//
//						// 如果产品列表中已经有这个 SKU，则累加数量
//						Optional<Product> existingProduct = products.stream()
//								.filter(p -> p.getSku().equals(subProduct.getSku()))
//								.findFirst(); // 这一步从筛选后的流中找到第一个满足条件的产品，并将其包装在一个 Optional 对象中。如果流中没有满足条件的产品，则返回一个空的 Optional
//
//						if (existingProduct.isPresent()) { // isPresent() 方法用于检查 Optional 是否包含一个非空的值。如果返回 true，表示找到了符合条件的产品；如果返回 false，则表示没有找到匹配的产品
//							Product existing = existingProduct.get();
//							existing.setOperSize(existing.getOperSize() + subProduct.getOperSize());  // 累加数量
//							existing.setAmount(existing.getAmount().add(subProduct.getAmount()));  // 累加金额
//						} else {
//							// 如果没有相同 SKU，添加新的产品
//							subProducts.add(subProduct);
//							additionalSubProducts.add(subProduct);
//						}
//					}
//				}
//				// 将原组合sku从products中移除
//				productsToRemove.add(item);
//			}
//		});
//
//		// 移除组合 SKU
//		products.removeAll(productsToRemove);
//
//		// 遍历完成后，再将额外的产品信息添加到 products 中
//		products.addAll(additionalSubProducts);
//
//		ObjectMapper objectMapper = new ObjectMapper();
//		try {
//			String json = objectMapper.writeValueAsString(products);
//			System.out.println(json);
//		} catch (JsonProcessingException e) {
//			e.printStackTrace();
//		}
		return products;
	}



	@Override
	public int disable(List<Long> ids) {
		if(ids.isEmpty()){
			throw new ServiceException("停用的产品列表为空，请检查!");
		}
		return productMapper.disable(ids);
	}

	@Override
	public int enable(List<Long> ids) {
		if(ids.isEmpty()){
			throw new ServiceException("启用的产品列表为空，请检查!");
		}
		return productMapper.enable(ids);
	}


	/**
	 * 导入产品表格数据
	 * @param file
	 * @return
	 */
	@Override
	@Transactional
	public int importVendorExcel(MultipartFile file) {
		int rows = 0;
		try (InputStream inputStream = file.getInputStream();
			 Workbook workbook = new XSSFWorkbook(inputStream)) {

			Sheet sheet = workbook.getSheetAt(0); // 读取第一个工作表
			int rowCount = sheet.getPhysicalNumberOfRows();
			if (rowCount <= 1) {
				throw new RuntimeException("Excel 数据为空");
			}

			for (int i = 1; i < rowCount; i++) { // 从第二行开始读取（第一行是表头）
				Row row = sheet.getRow(i);
				if (row == null || isRowEmpty(row)) { // **跳过空行**
					continue;
				}

				Product p = new Product();

				String oemName = getCellValue(row.getCell(5)).trim();//OEM
				validateString(oemName, i , "OEM");

				// 校验oem名称是否存在
				Oem oem = new Oem();
				oem.setName(oemName);
				oem = oemMapper.checkOemNameExists(oem);
				if(oem == null){
					throw new RuntimeException("第"+ ( i + 1 )+"行，OEM格式有误：" + oemName);
				}
				p.setOem(oem.getId());
				//校验sku
				String sku = getCellValue(row.getCell(0)).trim();//sku
				validateString(sku, i , "SKU");
				if(!sku.startsWith(oemName)){
					throw new RuntimeException("第"+ ( i + 1 )+"行，SKU格式有误：" + sku);
				}
				// 查询数据库，判断 SKU 是否已存在
				int skuCount = productMapper.countByProductSku(sku);
				if (skuCount > 0) {
					throw new RuntimeException("第 " + (i + 1) + " 行，SKU 已存在：" + sku);
				}
				p.setSku(sku);
				//校验名称
				String exclProductName = getCellValue(row.getCell(1)).trim();//名称
				validateString(sku, i , "名称");
				//检验产品类型
				String productCatesName = getCellValue(row.getCell(3)).trim();// 产品类型
				validateString(productCatesName, i , "产品类型");
				//查询是否存在对应的供应商类别
				ProductCates productCates = productCatesMapper.checkProductCatesNameExists(productCatesName);
				if(productCates == null){
					throw new RuntimeException("第"+ ( i + 1 )+"行，产品类型格式有误：" + productCatesName);
				}
				p.setCatesId(productCates.getId()); // 供应商类别
				//校验品牌
				String brandName = getCellValue(row.getCell(4)).trim();//品牌
				validateString(brandName, i , "品牌");
				AuthBrand authBrand = new AuthBrand();
				authBrand.setBrandName(brandName);
				//查询是否存在对应的品牌
				authBrand = authBrandMapper.checkBrandNameExists(authBrand);
				if(authBrand == null){
					throw new RuntimeException("第"+ ( i + 1 )+"行，品牌格式有误：" + brandName);
				}
				p.setBrandId(authBrand.getAuthBrandId());
				//检验规格型号
				String model = getCellValue(row.getCell(6)).trim();// 规格型号
				validateString(model, i , "规格型号");
				p.setModel(model);
				//检验颜色
				String colorName = getCellValue(row.getCell(18)).trim();// 规格型号
				validateString(colorName, i , "颜色");
//				Color color = new Color();
//				color.setColorName(colorName);
//				validateString(colorName, i , "颜色");
//				//查询是否存在对应的颜色
//				color = colorMapper.checkColorNameExists(color);
//				if(color == null){
//					throw new RuntimeException("第"+ ( i + 1 )+"行，颜色格式有误：" + colorName);
//				}
				//产品名称
				String productName = exclProductName + " " + model +" " + colorName+
						(authBrand.getParentId().equals("0") ? " " + brandName : "");
				p.setName(productName);
				//检验产品描述
				String desc = getCellValue(row.getCell(7)).trim();// 产品描述
				validateString(desc, i , "产品描述");
				p.setDesc(desc);
				//检验包装清单
				String packingList = getCellValue(row.getCell(8)).trim();// 包装清单
				validateString(packingList, i , "包装清单");
				p.setPackingList(desc);
				//属性:  (0:无，1:含电，2:液体，3:粉末，4:纯电、5:膏体、6:带磁、7:含非液体化妆品)
				String attribute = getCellValue(row.getCell(9)).trim(); // 读取并去除空格
				validateString(attribute, i, "属性");
				SysDictData dictData = new SysDictData();
				dictData.setDictType("sys_product_attribute");
				dictData.setDictLabel(attribute);
				//查询是否存在对应的属性
				dictData = sysDictDataMapper.checkDictLabelExists(dictData);
				if (dictData == null) {
					throw new RuntimeException("第 " + (i + 1) + " 行，属性值有误："+attribute);
				}
				// 设置值
				p.setAttribute(dictData.getDictValue());
				//质检方式
				String _inspectionMethod = getCellValue(row.getCell(23)).trim(); // 读取并去除空格
				validateString(_inspectionMethod, i, "质检方式");
				// 校验并转换
				Long inspectionMethod;
				if ("抽检".equals(_inspectionMethod)) {
					inspectionMethod = 0L;
				} else if ("全检".equals(_inspectionMethod)) {
					inspectionMethod = 1L;
				}else if("免检".equals(_inspectionMethod)){
					inspectionMethod = 2L;
				}else {
					throw new RuntimeException("第 " + ( i + 1) + " 行，属性值错误，必须是 '抽检' 或 '全检' 或 '免检'！");
				}
				p.setInspectionMethod(inspectionMethod);
				p.setProductRemarks(getCellValue(row.getCell(10)).trim());//备注
				p.setFlag(0);
				p.setStatus("0");
				p.setAddTime(DateUtils.getNowDate());
				p.setProNo(generateCodePlan());
				p.setSort(1L);
				//插入产品
				productMapper.insertProduct(p);
				Long productId = p.getId();

				//插入图片
				String imageUrl = getCellValue(row.getCell(2)).trim();
				if(imageUrl != null){
					imageUrl = ImageDownloader(imageUrl);//新图片路径
				}
				List<ProductImage> images = new ArrayList<>();
				if (imageUrl != null && !imageUrl.isEmpty()) { // **过滤空图片**
					ProductImage image = new ProductImage();
					image.setProductId(productId.intValue());
					image.setProductImagePath(imageUrl);
					image.setCreatedAt(new Date());
					images.add(image);
				}
				if (!images.isEmpty()) {
					productImageMapper.insertBatch(images);
				}

				// 插入产品SKU
				ProductSku productSku = new ProductSku();
				productSku.setProductId(productId);
				productSku.setDeleteStatus("0");
				//检验单品尺寸
				String size = getCellValue(row.getCell(11)).trim();// 单品尺寸
				validateString(size, i , "单品尺寸");
				productSku.setSize(size);
				//检验周转箱尺寸
				String containerSize = getCellValue(row.getCell(12)).trim();// 周转箱尺寸
				validateString(containerSize, i , "周转箱尺寸");
				productSku.setContainerSize(containerSize);
				//检验包装尺寸
				String packageSize = getCellValue(row.getCell(13)).trim();// 包装尺寸
				validateString(packageSize, i , "包装尺寸");
				productSku.setPackageSize(packageSize);
				//检验单品重量
				String _productWeight = getCellValue(row.getCell(14)).trim();// 单品重量
				// 使用通用校验方法
				BigDecimal productWeight = validateBigDecimal(_productWeight, i, "单品重量");
				productSku.setProductWeight(productWeight);
				//检验周转箱重量
				String _turnoverBoxWeight = getCellValue(row.getCell(15)).trim();// 周转箱重量
				// 使用通用校验方法
				BigDecimal turnoverBoxWeight = validateBigDecimal(_turnoverBoxWeight, i, "周转箱重量");
				productSku.setTurnoverBoxWeight(turnoverBoxWeight);
				//检验产品重量
				String _packageWeight = getCellValue(row.getCell(16)).trim();// 产品重量
				// 使用通用校验方法
				BigDecimal packageWeight = validateBigDecimal(_packageWeight, i, "产品重量");
				productSku.setPackageWeight(packageWeight);
				//检验商品价格
				String _price = getCellValue(row.getCell(17)).trim();// 商品价格
				// 使用通用校验方法
				BigDecimal price = validateBigDecimal(_price, i, "商品价格");
				productSku.setPrice(price);
				//交货周期
				productSku.setLeadTime(getCellValue(row.getCell(19)).trim());
				//交货周期
				productSku.setVendorId(null);
				//检验装箱数
				String _boxSize = getCellValue(row.getCell(21)).trim();// 装箱数
				validateString(_boxSize, i, "装箱数");
				productSku.setBoxSize(Long.valueOf(_boxSize));
				//商品材质
				productSku.setProductMaterial(getCellValue(row.getCell(22)).trim());
				//颜色
				productSku.setColorId(colorName);
				productSkuMapper.insertProductSku(productSku);


				//插入质检
				List<ProductCustomQualityItem> qualityItems = new ArrayList<>();
				ProductCustomQualityItem item = new ProductCustomQualityItem();
				//质检项
				String inspectionItem = getCellValue(row.getCell(24)).trim();// 质检项
				//validateString(inspectionItem, i , "质检项");
				//质检内容
				String inspectionContent = getCellValue(row.getCell(25)).trim();// 质检项
				//validateString(inspectionContent, i , "质检内容");
				item.setProductId(productId.intValue());
				item.setInspectionItem(inspectionItem);
				item.setInspectionContent(inspectionContent);
				qualityItems.add(item);
				if (!qualityItems.isEmpty()) {
					productCustomQualityItemMapper.insertBatch(qualityItems);
				}

			}
			rows = rowCount - 1;
		} catch (Exception e) {
			throw new RuntimeException("导入 Excel 失败：" + e.getMessage());
		}

		return rows;
	}
	/**
	 * 检查 Excel 行是否为空
	 */
	private boolean isRowEmpty(Row row) {
		if (row == null) {
			return true;
		}
		for (int c = row.getFirstCellNum(); c < row.getLastCellNum(); c++) {
			Cell cell = row.getCell(c);
			if (cell != null && cell.getCellType() != CellType.BLANK &&
					(cell.getCellType() != CellType.STRING || !cell.getStringCellValue().trim().isEmpty())) {
				return false; // 发现非空单元格，行不是空的
			}
		}
		return true; // 整行是空的
	}

	/**
	 * 处理空字符串转换为 Long
	 */
	private Long parseLong(String value) {
		try {
			return value == null || value.isEmpty() ? null : Long.parseLong(value);
		} catch (NumberFormatException e) {
			return null;
		}
	}
	/**
	 * 处理空字符串转换为 BigDecimal
	 */
	private BigDecimal parseBigDecimal(String value) {
		try {
			return value == null || value.isEmpty() ? null : new BigDecimal(value);
		} catch (NumberFormatException e) {
			return null;
		}
	}
	/**
	 * 获取单元格数据
	 */
	private String getCellValue(Cell cell) {
		if (cell == null) return "";
		if (cell.getCellType() == CellType.NUMERIC) {
			double value = cell.getNumericCellValue();
			if (value == Math.floor(value)) {  // 判断是否是整数
				return String.valueOf((long) value); // 转换为 long，去掉 .0
			} else {
				return String.valueOf(value); // 仍然返回小数
			}
		}
		return cell.getStringCellValue().trim();
	}
	/**
	 * 校验字符串是否为空
	 */
	private void validateString(String value, int rowIndex, String fieldName) {
		if (value == null || value.trim().isEmpty()) {
			throw new RuntimeException("第 " + (rowIndex+1) + " 行，" + fieldName + " 不能为空！");
		}
	}
	/**
	 * 校验并转换 `BigDecimal`
	 * @param value  单元格值（字符串类型）
	 * @param rowIndex Excel 行号
	 * @param fieldName 字段名
	 * @return `BigDecimal` 类型的值
	 */
	public BigDecimal validateBigDecimal(String value, int rowIndex, String fieldName) {
		validateString(value, rowIndex, fieldName); // 先检查是否为空
		try {
			return new BigDecimal(value.trim());
		} catch (NumberFormatException e) {
			throw new RuntimeException("第 " + rowIndex + " 行，" + fieldName + " 格式错误，必须是数字！");
		}
	}
	/**
	 * 上传图片
	 */
	/**
	 * 下载图片
	 */
	private String ImageDownloader(String imageUrl) {
		if (imageUrl == null || imageUrl.trim().isEmpty()) {
			return ""; // 返回空字符串，表示没有下载
		}

		try {
			String returnFilePath = generateFilePath("jpg"); // 生成存储路径
			String fullLocalPath = basePath + "/upload/" + returnFilePath.replace(URL_PREFIX, "");

			FileUtils.copyURLToFile(new URL(imageUrl), new File(fullLocalPath));

			return returnFilePath; // 返回图片路径
		} catch (IOException e) {
			return ""; // 返回空字符串或默认图片路径
		}
	}

	/**
	 * 上传图片
	 */
	private  String generateFilePath(String extension) {

		// 1️⃣ 获取当前日期
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
		String datePath = sdf.format(new Date()); // 生成 "2025/03/14"

		// 2️⃣ 组合完整路径（服务器存储路径）
		String fullSavePath = basePath + "/upload/" + datePath + "/";

		// 3️⃣ 确保目录存在
		File directory = new File(fullSavePath);
		if (!directory.exists()) {
			directory.mkdirs(); // 递归创建目录
		}

		// 4️⃣ 生成唯一文件名
		String uniqueFileName = UUID.randomUUID().toString().replaceAll("-", "") + "." + extension;

		// ️5️⃣ 生成返回路径（以 `/profile/upload/` 开头）
		String returnFilePath = URL_PREFIX + datePath + "/" + uniqueFileName;

		return returnFilePath; // 返回以 `/profile/upload/` 开头的路径
	}
}
